#include "volOR.h"
#include <memory.h>


void volOR::updateImageDataRef(imgData *p){
	this->p_img_data=p;
}


void volOR::test(float P[3][4], float cam_dir[3],float &score, int &or_index, volParticle_s &particle){
	int n_chd = this->children.size();
	score = -1e10;
	std::deque<int> deform_list;
	for( int i_chd = 0; i_chd<n_chd; ++i_chd){
		std::deque<int> current_deform_list;
		float current_score = -1e10;
		this->children[i_chd]->test(P,cam_dir,current_score,current_deform_list);
		if(current_score>score){
			score = current_score;
			or_index = i_chd;
			deform_list = current_deform_list;
		}
	}
	for(int row = 0; row<3; ++row){
		memcpy(particle.P[row],P[row],sizeof(float)*4);
	}
	memcpy(particle.cam_dir, cam_dir,sizeof(float)*4);

	particle.deform_list = deform_list;
	particle.id = this->id;
	particle.score = score;
}

void volOR::inference(){
	int n_chd = this->children.size();
	for( int i_chd = 0; i_chd<n_chd; ++i_chd){
		int n_ptc = children[i_chd]->vol_particle_list.size();
		for(int i_ptc= 0; i_ptc<n_ptc; ++i_ptc){
			volParticle_s &ptc = this->children[i_chd]->vol_particle_list.front();
			
			this->updateParticleList(ptc,i_chd);

			children[i_chd]->vol_particle_list.pop_front();
		}
	}
}

void volOR::argMax(volParticle_s &ptc,int or_index, float *p_template){
	//

	//int child_id=this->children[or_index]->id;
	//if( or_index != child_id) {
	//	printf("warning, this or_index id is not equal to child_id\n");
	//	return;
	//}
	//
	this->children[or_index]->argMax(ptc, p_template);

}



bool volOR::updateParticleList(volParticle_s & particle, int or_index){
	if( particle.score<-1e6) return false;
	if( this->vol_particle_list.empty()){
		vol_particle_list.push_back(particle);
		particle_or_index.push_back(or_index);
		return true;
	}
	std::list<volParticle_s>::iterator itr = vol_particle_list.begin();
	std::list<int>::iterator itr_index = particle_or_index.begin();
	for(;itr!=vol_particle_list.end();){
		if(particle.score>=itr->score){
			vol_particle_list.insert(itr,particle);
			particle_or_index.insert(itr_index,or_index);
			if(vol_particle_list.size()>PR_QUEUE_SIZE){
				vol_particle_list.pop_back();
				particle_or_index.pop_back();
			}
			return true;
		}
		++itr_index;
		++itr;
	}

	if( this->vol_particle_list.size()<PR_QUEUE_SIZE){
		vol_particle_list.push_back(particle);
		particle_or_index.push_back(or_index);
		return true;
	}


	return false;

}


float *volOR::SWTest(view_s &view,bool use_color){
	int sx = this->p_img_data->sx;
	int sy = p_img_data->sy;
	int n_chd = children.size();
	if(n_chd ==1){
		return children[0]->SWTest(view, use_color);
	}
	
	/*warning:: code below is not debugged.*/

	float *max_map = new float[sx*sy];
	int *arg_max_map = new int[sx*sy];
	for(int i_pix=0; i_pix<sx*sy; ++i_pix){
		max_map[i_pix] = NEGMAX;
		arg_max_map[i_pix]=-1;
	}

	for(int i_chd=0; i_chd<n_chd; ++i_chd){
		float *score_map = children[i_chd]->SWTest(view,use_color);
		for(int i_pix=0; i_pix<sx*sy; ++i_pix){
			max_map[i_pix]=std::max(score_map[i_pix],max_map[i_pix]);
		}
		delete[] score_map;
	}

	delete[] arg_max_map;
	return max_map;
}

